package authorization

import (
	"demo/flutter_server/common/utils"
	"encoding/base64"
	"errors"
	"strings"
	"time"
)

var jwtKey = []byte("secret")

type AuthorizationService struct {
}

func NewAuthenticationService() *AuthorizationService {
	return &AuthorizationService{}
}

func (service *AuthorizationService) Login(username string, password string) (*User, string, error) {
	if username == "admin" && password == "123123" {
		if token, err := utils.GenerateJwtToken(jwtKey, time.Now().Add(time.Hour*24*7), username); err != nil {
			return nil, "", err
		} else {
			user := service.getUser(username)
			return user, token, nil
		}
	}
	return nil, "", errors.New("invalid username or password")
}

func (service *AuthorizationService) Refresh(token string) (*User, string, error) {
	expireAt, username, err := service.getPayload(token)
	if err != nil {
		return nil, "", err
	}
	if expireAt < time.Now().Unix() {
		return nil, "", errors.New("token expired")
	}
	// 如果大于1天，则返回当前token，防止恶意刷新
	if expireAt > time.Now().Unix()+3600*24*7 {
		user := service.getUser(username)
		return user, token, nil
	}
	if token, err := utils.GenerateJwtToken(jwtKey, time.Now().Add(time.Hour*24*7), username); err != nil {
		return nil, "", err
	} else {
		user := service.getUser(username)
		return user, token, nil
	}
}

func (service *AuthorizationService) ValidateToken(token string) error {
	return utils.ValidateJwtToken(jwtKey, token)
}

func (t *AuthorizationService) getUser(username string) *User {
	return &User{
		ID:       1,
		Username: "admin",
		Nickname: "admin",
		Avatar:   "",
	}
}

func (service *AuthorizationService) getPayload(token string) (int64, string, error) {
	parts := strings.Split(token, ".")
	if len(parts) != 3 {
		return 0, "", errors.New("invalid token format")
	}
	payload := parts[1]
	decodedBytes, err := base64.RawURLEncoding.DecodeString(payload)
	if err != nil {
		return 0, "", err
	}

	if payloadMap, err := utils.ParseMap(decodedBytes); err != nil {
		return 0, "", err
	} else {
		username, _ := payloadMap["username"].(string)
		expireAt, _ := payloadMap["exp"].(int64)
		return expireAt, username, nil
	}
}